/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *   gbx-emu - debugger.h                                                  *
 *   gbx-emu homepage: http://code.google.com/p/gbx-emu/                   *
 *   Copyright (C) 2009 olejl77@gmail.com                                  *
 *                                                                         *
 *   This program is free software: you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation, either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the          *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef DEBUGGER_H
#define DEBUGGER_H
#include "common.h"
#include <QMutex>
#include <QWaitCondition>

typedef struct _breakpoint {
    u16 address;
    u32 flags;
} breakpoint;

enum { MAXBP = 0x10 };
enum {
    BPT_FLAG_ENABLED     = 0x01,
    BPT_FLAG_CONDITIONAL = 0x02,
    BPT_FLAG_COUNTER     = 0x04,
    BPT_FLAG_READ        = 0x08,
    BPT_FLAG_WRITE       = 0x10,
    BPT_FLAG_EXEC        = 0x20,
    BPT_FLAG_LOG         = 0x40, // Log to the console when this breakpoint hits.
    BPT_FLAG_NEXT        = 0x80, // Should be removed after triggered once
};

class Gameboy;
class Cpu;
class DebuggerWidget;
class MainWindow;
class Memory;
class Log;
class Debugger : public Common
{
private:
    Gameboy *_gb;
    Cpu *_cpu;
    MainWindow *_ui;
    Memory *_mem;
    DebuggerWidget *_dbgWidget;
    Log *_log;

    u32 _ptrBreakpoint;
    bool _enabled;
    u32 _lastAction;
    QMutex _mutex;
    QWaitCondition _condition;

public:
    Debugger(Gameboy *ptr);
    ~Debugger();
    void setCpu(Cpu *ptr) { _cpu = ptr; }
    void setUi(MainWindow *ptr) { _ui = ptr; }
    void setMemory(Memory *ptr) { _mem = ptr; }
    void setLog(Log *ptr) { _log = ptr; }

    void dbgStart();
    void enableDebugger(bool enabled);
    void debuggerAction(u32 action);
    void debuggerUpdate(u16 pc);
    bool addBreakpoint(u16 addr);
    bool addBreakpoint(u16 addr, u32 flags);
    bool addBreakpointStruct(breakpoint *bp);
    void removeBreakpoint(u32 num);
    void enableBreakpoint(u32 num);
    void disableBreakpoint(u32 num);
    bool checkBreakpoint(u16 addr);
    u32 getNumBreakpoint();
    _breakpoint getNumBreakpoint(u32 num);
    _breakpoint bpArray[MAXBP];

};

const u8 opcodeLength [] = {
1,3,1,1,1,1,2,1,3,1,1,1,1,1,2,1,//0x00
1,3,1,1,1,1,2,1,2,1,1,1,1,1,2,1,//0x10
2,3,1,1,1,1,2,1,2,1,1,1,1,1,2,1,//0x20
2,3,1,1,1,1,2,1,2,1,1,1,1,1,2,1,//0x30
1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,//0x40
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//0x50
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//0x60
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//0x70
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//0x80
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//0x90
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//0xa0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,//0xb0
1,1,3,3,3,1,2,1,1,1,3,2,3,3,2,1,//0xc0  //0xcb is always 2 (I think)
1,1,3,0,3,1,2,1,1,1,3,0,3,0,0,1,//0xd0
2,1,1,0,0,1,2,1,2,1,3,0,0,0,2,1,//0xe0
2,1,1,1,0,1,2,1,2,1,3,1,0,0,2,1 //0xf0
};
#endif // DEBUGGER_H
